import { PageEnum } from '@/constants'
import { PAGE_NOT_FOUND_ROUTE } from './routes'
import { router } from '@/router'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { useAuthStoreWithout, useUserStoreWithout, useLockStoreWithout, useMenuStoreWithout } from '@/store'

//页面加载池
const LOADED_PAGE_POOL = new Map<string, boolean>()

//路由白名单
const whitePathList: string[] = [PageEnum.BASE_LOGIN, PageEnum.BASE_LOCK]

//初始化基础路由守卫, 加载页面进度条
export function initBasicGuard() {
	router.beforeEach((to) => {
		NProgress.configure({ showSpinner: false, speed: 500 })
		// 已加载的页面，不在加载页面进度条
		to.meta.loaded = !!LOADED_PAGE_POOL.get(to.path)
		if (to.meta.title && !to.meta.loaded) NProgress.start()
		return true
	})

	// 路由加载后
	router.afterEach((to) => {
		LOADED_PAGE_POOL.set(to.path, true)
		if (to.meta.title) {
			NProgress.done()
		}
	})
}

// 初始化权限路由守卫
export function initAuthGuard() {
	router.beforeEach(async (to, from, next) => {
		const userStore = useUserStoreWithout()
		const lockStore = useLockStoreWithout()
		const authStore = useAuthStoreWithout()
		const menuStore = useMenuStoreWithout()
		const homePage = userStore.userInfo?.homePath ? userStore.userInfo?.homePath : PageEnum.BASE_HOME
		const loginPage = PageEnum.BASE_LOGIN
		const lockPage = PageEnum.BASE_LOCK
		const token = userStore.accessToken

		//锁屏状态下路由重定向
		if (lockStore.lockInfo?.isLock && to.path !== lockPage) {
			next(lockPage)
			return
		}

		//白名单不考虑Token
		if (whitePathList.includes(to.path as PageEnum)) {
			if (to.path === loginPage && token) {
				//token存在时，访问登录页
				const isSessionTimeout = userStore.sessionTimeout
				try {
					await userStore.afterLoginAction()
					if (!isSessionTimeout) {
						next((to.query?.redirect as string) || '/')
						return
					}
				} catch {
					/* empty */
				}
				next({ path: homePage })
				return
			}

			if (to.path === lockPage && !lockStore.lockInfo?.isLock) {
				const redirect = decodeURIComponent((from.query.redirect as string) || homePage)
				next(redirect)
				return
			}
			next()
			return
		}
		if (token) {
			//Token存在
			if (to.path === loginPage) {
				//访问登录页时，直接跳转到首页
				next({ path: homePage })
			} else {
				// 用户上次提取时间为0时
				if (userStore.lastUpdateTime === 0) {
					try {
						await userStore.getUserInfoAction()
					} catch (err) {
						next()
						return
					}
				}
				// 用户权限路由记录时间为0时
				if (authStore.lastBuildRouteTime === 0) {
					try {
						const routes = await authStore.buildRoutesAction()
						routes.forEach((route) => {
							router.addRoute(route)
						})

						// 用户权限路由变更时，必须重新构建菜单
						await menuStore.buildMenuAction()
					} catch (err) {
						next()
						return
					}

					if (to.name == PAGE_NOT_FOUND_ROUTE.name) {
						// 动态添加路由后，此处应当重定向到fullPath，否则会加载404页面内容
						next({ path: to.fullPath, replace: true, query: to.query })
						return
					}
				}
				// 根据用户权限路由构建菜单记录时间为0时
				if (menuStore.lastBuildMenuTime === 0) {
					await menuStore.buildMenuAction()
				}

				// 请求带有 redirect 重定向时，登录自动重定向到该地址
				const redirect = decodeURIComponent((from.query.redirect as string) || to.path)
				if (to.path === redirect) {
					next()
				} else {
					from.query = {} //*****清除掉原重定向的参数
					next({ path: redirect })
				}
			}
		} else {
			// Token不存在
			if (to.meta.ignore_auth) {
				// 是否需要权限判断属性meta.ignore_auth
				next()
			} else {
				// 重定向登录
				const redirectData: {
					path: string
					replace: boolean
					query?: Recordable<string>
				} = {
					path: loginPage,
					replace: true
				}
				if (to.path) {
					redirectData.query = {
						...redirectData.query,
						redirect: to.path
					}
				}
				next(redirectData)
			}
		}
	})
}
